using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using Ricciolo.PaperBoy.UI;
using System.ComponentModel;
using Ricciolo.PaperBoy.Feeds;
using System.Collections;
using System.Diagnostics;
using System.Windows.Controls.Primitives;
using System.Configuration;
using TreeViewItem=Ricciolo.PaperBoy.UI.TreeViewItem;

namespace Ricciolo.PaperBoy.Themes.Classic
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>

    public partial class MainWindow : Ricciolo.PaperBoy.UI.MainWindow
    {

        private GridViewColumnHeader _lastHeaderClicked = null;
        private ListSortDirection _lastDirection = ListSortDirection.Ascending;
        private SortDescription? feedsListSort = null;
        private delegate void MethodInvoker();

        public MainWindow()
        {

        }

        public MainWindow(ApplicationSettingsBase applicationSettings)
            : base(applicationSettings)
        {
            InitializeComponent();
        }

        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);

            //GlassHelper.ExtendGlassFrame(this, new Thickness(-1));
            this.feedItems.SelectedItemChanged += feedItems_SelectedItemChanged;
            this.feedsList.SelectedItemChanged += feedsList_SelectedItemChanged;

            // Handle navigation of first Tab
            ((Frame)((TabItem)this.ieTab.Items[0]).Content).Navigating += Frame_Navigating;
        }

        void Frame_Navigating(object sender, System.Windows.Navigation.NavigatingCancelEventArgs e)
        {
            e.Cancel = true;
            
            this.Navigate(e.Uri, IETabControl.BlankTarget);
        }

        void feedsList_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            // Keep syncronize to CurrentFeed property
            if (this.CurrentFeed != feedsList.SelectedItem)
                this.CurrentFeed = feedsList.SelectedItem as IFeed;

            // Save previous view mode
            if (e.OldValue is IFeed)
            {
                FeedSetting fs = GetFeedSetting(((IFeed)e.OldValue));
                fs.ViewingMode = documentReader.ViewingMode;
                fs.Zoom = documentReader.Zoom;
            }
            // Load view mode
            if (e.NewValue is IFeed)
            {
                FeedSetting fs = GetFeedSetting(((IFeed)e.NewValue));
                documentReader.ViewingMode = fs.ViewingMode;
                documentReader.Zoom = fs.Zoom;
            }
        }

        void feedItems_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<Object> e)
        {
            // TODO: check if it is a comment...
            this.CurrentFeedItem = e.NewValue;

            TreeListViewItem titem = this.feedItems.ItemContainerGenerator.ContainerFromItem(this.feedItems.Items.CurrentItem) as TreeListViewItem;
            if (titem != null && !titem.IsFocused)
            {
                this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new MethodInvoker(delegate()
                {
                    titem.Focus();
                }));
            }

            this.documentReader.ScrollToTop();
            // Select first tab
            this.ieTab.SelectedIndex = 0;
        }

        void feedsList_Expanded(object s, RoutedEventArgs e)
        {
            TreeViewItem item = e.OriginalSource as TreeViewItem;
            if (item == null) return;

            SetFeedExpanded(item, true);
        }

        void feedsList_Collapsed(object s, RoutedEventArgs e)
        {
            TreeViewItem item = e.OriginalSource as TreeViewItem;
            if (item == null) return;

            SetFeedExpanded(item, false);
        }

        void SetFeedExpanded(TreeViewItem item, bool isExpanded)
        {
            FeedFolder folder = item.Header as FeedFolder;
            if (folder == null) return;

            FeedSetting setting = this.GetFeedSetting(folder);
            setting.IsExpanded = isExpanded;
        }

        void feedsItems_SortColumn(object s, RoutedEventArgs e)
        {
            GridViewColumnHeader headerClicked = e.OriginalSource as GridViewColumnHeader;
            ListSortDirection direction;

            if (headerClicked != null)
            {
                if (headerClicked.Role != GridViewColumnHeaderRole.Padding)
                {
                    // If header was chaged direction is asc
                    if (headerClicked != _lastHeaderClicked)
                        direction = ListSortDirection.Ascending;
                    else
                    {
                        // Invert direction
                        if (_lastDirection == ListSortDirection.Ascending)
                            direction = ListSortDirection.Descending;
                        else
                            direction = ListSortDirection.Ascending;
                    }

                    // Sort using header name
                    if (!(headerClicked.Column is GridViewSortColumn)) return;
                    string header = ((GridViewSortColumn)headerClicked.Column).SortPropertyName;

                    // Get the view
                    ICollectionView dataView = CollectionViewSource.GetDefaultView(((ItemsControl)e.Source).ItemsSource);

                    // Disable auto refresh
                    using (IDisposable r = dataView.DeferRefresh())
                    {
                        if (feedsListSort.HasValue)
                            dataView.SortDescriptions.Remove(feedsListSort.Value);

                        feedsListSort = new SortDescription(header, direction);
                        // Set sorting expression
                        dataView.SortDescriptions.Insert(0, feedsListSort.Value);
                    }

                    _lastHeaderClicked = headerClicked;
                    _lastDirection = direction;
                }
            }
        }

        #region Protected

        protected override void CreateSettingsProperties()
        {
            base.CreateSettingsProperties();

            GridLengthConverter converter = new GridLengthConverter();
            this.CreateSettingsProperty("mainGrid_ColumnWidth", converter.ConvertToString(new GridLength(1, GridUnitType.Star)));
            this.CreateSettingsProperty("feedGrid_RowHeight", converter.ConvertToString(new GridLength(1, GridUnitType.Star)));

            for (int x = 0; x < this.feedItems.Columns.Count; x++)
                this.CreateSettingsProperty("feedItems_Column" + x, 0d);

        }

        protected override void LoadSettings()
        {
            base.LoadSettings();

            GridLengthConverter converter = new GridLengthConverter();
            mainGrid.ColumnDefinitions[0].Width = (GridLength)converter.ConvertFromString(this.Settings["mainGrid_ColumnWidth"].ToString());
            feedGrid.RowDefinitions[0].Height = (GridLength)converter.ConvertFromString(this.Settings["feedGrid_RowHeight"].ToString());

            // Load feedItems columns
            for (int x = 0; x < this.feedItems.Columns.Count; x++)
            {
                double v = (double)this.Settings["feedItems_Column" + x];
                if (v > 0)
                    this.feedItems.Columns[x].Width = v;
            }
        }

        protected override void SaveSettings()
        {
            base.SaveSettings();

            GridLengthConverter converter = new GridLengthConverter();
            if (mainGrid.ColumnDefinitions[0].Width.Value != 1)
                this.Settings["mainGrid_ColumnWidth"] = converter.ConvertToString(new GridLength(mainGrid.ColumnDefinitions[0].Width.Value));
            if (feedGrid.RowDefinitions[0].Height.Value != 1)
                this.Settings["feedGrid_RowHeight"] = converter.ConvertToString(new GridLength(feedGrid.RowDefinitions[0].Height.Value));

            // Save feedItems columns
            for (int x = 0; x < this.feedItems.Columns.Count; x++)
            {
                this.Settings["feedItems_Column" + x] = this.feedItems.Columns[x].ActualWidth;
            }
        }

        protected override void Navigate(Uri url, String targetName)
        {
            this.ieTab.Navigate(url, targetName);
        }

        protected override void OnGotoNextUnreadItemCanExecute(object s, CanExecuteRoutedEventArgs e)
        {
            base.OnGotoNextUnreadItemCanExecute(s, e);

            e.CanExecute |= documentReader.CanGoToNextPage;
        }

        protected override void OnCurrendFeedChanged(DependencyObject s, DependencyPropertyChangedEventArgs e)
        {
            base.OnCurrendFeedChanged(s, e);

            ItemContainerGenerator generator = this.feedsList.ItemContainerGenerator;

            bool found = false;
            while (!found)
            {
                IFeed feed = (IFeed)this.CurrentFeed;
                while (feed != null)
                {
                    // Find container by feed
                    Ricciolo.PaperBoy.UI.TreeViewItem container = (Ricciolo.PaperBoy.UI.TreeViewItem)((System.Windows.Controls.ItemContainerGenerator)generator).ContainerFromItem(feed);
                    if (container == null)
                        feed = feed.Parent;
                    else
                    {
                        if (feed == this.CurrentFeed)
                        {
                            container.Focus();
                            found = true;
                        }
                        else
                        {
                            container.IsExpanded = true;
                            // Ensure child creation
                            if (container.ItemContainerGenerator.Status == GeneratorStatus.NotStarted)
                                container.Measure(Size.Empty);
                        }
                        generator = container.ItemContainerGenerator;
                        break;
                    }
                }
                if (feed == null)
                    break;
            }

        }

        protected override void OnGotoNextUnreadItemExecuted(object s, ExecutedRoutedEventArgs e)
        {
            // Scroll down until it reachs end of the document
            if (documentReader.CanGoToNextPage)
            {
                documentReader.PageDown();
            }
            else
            {
                // Go to next unread items
                base.OnGotoNextUnreadItemExecuted(s, e);
            }
        }

        #endregion
    }
}